<?php
declare(strict_types=1);

namespace App\Third\Service\Trade;


use App\Common\Constants\Stakeholder;
use App\Order\Model\KzRefundLogModel;
use App\Order\Model\OrderModel;
use App\Order\Model\WxRefundLogModel;
use App\Resource\Service\BuildGoodsService;
use App\Third\Model\ShopLsyGoodsInfoModel;
use App\Third\Model\ShopLsyGoodsStockModel;
use App\Third\Model\WxDedoLogModel;
use App\Third\Service\Lsy\LsyMainGoodsService;
use App\Third\Service\Wx\WxDeliverService;
use App\Third\Service\Wx\WxMainDeliverService;
use Hyperf\Di\Annotation\Inject;
use App\Resource\Model\GoodsListModel;
use App\Resource\Model\GoodsModel;
use App\Resource\Model\ShopModel;
use App\Third\Model\CrmMenuGoodsModel;
use App\Common\Constants\ErrorCode;
use App\Common\Service\BaseService;
use App\Third\Model\ShopSchemeModel;
use App\Third\Model\CrmMenuGoodsCodeModel;
use App\Third\Model\ShopSchemeGoodsPriceModel;
use App\Order\Service\OrderService;

class SourceService extends BaseService
{

    /**
     * @Inject()
     * @var LsyMainGoodsService
     */
    private $lsyMainGoodsService;
    /**
     * 获取吾享商品编码列表
     * @param array $where
     * @param int $perPage
     * @param array $field
     * @param string $type
     * @return array
     */
    public function getCrmGoodsList(array $where, int $perPage = 30, array $field = ['*'], string $type = '')
    {
        switch ($type) {
            case 'lsy':
                $query = ShopLsyGoodsInfoModel::query();
                break;
            case 'wx':
                $query = CrmMenuGoodsCodeModel::query();
                break;
            case 'lsyScheme':
                $query = ShopSchemeGoodsPriceModel::query();
                break;
        }
        if (!empty($where['title'])) {
            if (is_numeric($where['title'])) {
                if ($type == 'lsy') {
                    $query->where('id', '=', $where['title']);
                } elseif ($type == 'wx') {
                    $query->where('itemCode', '=', $where['title']);
                }elseif($type == 'lsyScheme'){
                    $query->where('crm_goods_id', '=', $where['title']);
                }
            } else {
                $query->where('name', 'LIKE', '%' . $where['title'] . '%');
            }
        }
        // 龙收银应用方案
        !empty($where['schemeID']) && $query->where('schemeID', '=', $where['schemeID']);
        $list = $query->Paginate($perPage, $field);
        return ['code' => ErrorCode::SUCCESS, 'data' => $list];
    }
    /**
     * 吾享拉取菜单
     * @return mixed
     */
    public function getCrmGoodsInfoCode()
    {
        $beginTime = time();
        $resSuccessArr = $resErrorArr = [];
        if ($this->isDevelopment()) {
            // 测试环境
            $code = 9700;
        } else {
            // 生产环境
            $code = 173627;
        }
        $this->getCrmGoodsCodeTask($code);
        $resSuccessArr[] = $code;
        $resMsg = '吾享拉取总部集团菜品执行完成-';
        if ($resSuccessArr) {
            $resSuccessStr = implode(',', $resSuccessArr);
            $resMsg .= '门店拉取成功：' . $resSuccessStr;
        }
        if ($resErrorArr) {
            $resErrorStr = implode(',', $resErrorArr);
            $resMsg .= '拉取失败：' . $resErrorStr;
        }
        if (!$resSuccessArr && !$resErrorArr) {
            $resMsg .= '暂无数据';
        }
        $resMsg .= '-消耗时间' . (time() - $beginTime) . 's';
        return ['code' => 0, 'msg' => $resMsg, 'data' => []];
    }

    /**
     * 获取吾享菜品
     * @param int $CrmShopID
     * @return mixed
     */
    public function getCrmGoodsCodeTask(int $CrmShopID)
    {
        $temp_data = [
            'mcId' => $CrmShopID,
            'type' => 1,
        ];
        $data = $this->container->get(WxMainDeliverService::class)->GetItemInfoList($temp_data);
        $goods_arr = $data['iteminfolist'];
        $CrmGoodsData = [];
        foreach ($goods_arr as $vo) {
            $CrmGoodsData [] = [
                'CrmShopID' => $CrmShopID,
                'itemCode' => $vo['itemcode'],
                'name' => $vo['name'],
            ];
        }
        $where = ['CrmShopID' => $CrmShopID];
        CrmMenuGoodsCodeModel::where($where)->delete();
        CrmMenuGoodsCodeModel::insert($CrmGoodsData);
        return ['code' => 0, 'msg' => '拉取成功', 'data' => []];
    }
    /**
     * 吾享外卖异常订单
     * @param array $where
     * @param int $perPage
     * @param array|string[] $field
     *
     * @return array
     */
    public function wxOrderLog(array $where = [], int $perPage = 15, array $field = ['*'])
    {
        $query = OrderModel::query();
        !empty($where['order_no'])
        && $query->where('order_no', '=', $where['order_no']);
        !empty($where['order_phone'])
        && $query->where('order_phone', '=', $where['order_phone']);
        !empty($where['shop_id'])
        && $query->where('shop_id', '=', $where['shop_id']);
        isset($where['status'])
        && $query->where('status', '=', $where['status']);
        !empty($where['order_type'])
        && $query->where('order_type', '=', $where['order_type']);
        !empty($where['deal_type'])
        && $query->where('deal_type', '=', $where['deal_type']);
        !empty($where['pay_at_start'])
        && $query->whereDate('pay_at', '>=', $where['pay_at_start']);
        !empty($where['pay_at_end'])
        && $query->whereDate('pay_at', '<=', $where['pay_at_end']);
        $query->where('is_pay', '=', 1);
        $query->where('pos_type', '=', 2);

        $data = $query->orderBy('create_at', 'desc')->paginate($perPage, $field);

        return ['code' => ErrorCode::SUCCESS, 'data' => $data];
    }
    /**
     * 获取龙收银商品信息
     * @param $goods_crm_code
     * @param $goods_id
     * @param $shop_id
     * @return array
     */
    public function getLsyGoodsInfo($goods_crm_code, $goods_id, $shop_id)
    {
        $goodsArr = GoodsModel::query()->find($goods_id, ['scant_id', 'ratio']);
        $goodsListArr = GoodsListModel::query()->where('goods_id', $goods_id)->select('goods_id', 'goods_spec', 'price_selling', 'price_market', 'number_stock')->first();
        $CrmShopID = ShopModel::query()->where('shop_id', $shop_id)->value('lsy_shop_no');
        $where = ['crm_goods_id' => $goods_crm_code, 'CrmShopID' => $CrmShopID];
        $crm_goods_Info = CrmMenuGoodsModel::query()->where($where)->first();
        $itemCode = $crm_goods_Info->itemCode ?? 0;
        $price_selling = $crm_goods_Info->price ?? number_format(0, 2);
        $price_market = $crm_goods_Info->stdPrice ?? number_format(0, 2);
        $surplusQuantity = $crm_goods_Info->surplusQuantity ?? 0;
        $salesQuantity = $crm_goods_Info->salesQuantity ?? 0;
        if ($goodsArr->scant_id == Stakeholder::GOODS_NON_STANDARD) {
            if ($price_selling != 0.00) {
                $price_selling = round(($price_selling / 1000) * $goodsArr->ratio, 2);
                $price_market = round(($price_market / 1000) * $goodsArr->ratio, 2);
            }
            if ($price_selling != 0) {
                $surplusQuantity = floor(($surplusQuantity * 1000) / $goodsArr->ratio);
            }
        }
        if ($goodsArr->scant_id == Stakeholder::GOODS_STANDARD) {
            $price_selling = $goodsListArr->price_selling;
            $price_market = $goodsListArr->price_market;
        }
        $data = [];
        $data['price_selling'] = $price_selling;
        $data['price_market'] = $price_market;
        $data['surplus_quantity'] = $surplusQuantity;
        $data['sales_quantity'] = $salesQuantity;
        $data['item_code'] = $itemCode;
        return ['code' => ErrorCode::SUCCESS, 'data' => $data];
    }

    /**
     * 获取龙收银应用方案列表
     * @param array $where
     * @param int $perPage
     * @param array $field
     * @return array
     */
    public function getLsyApplicationScheme(array $where = [], int $perPage = 15, array $field = ['*'])
    {
        $query = ShopSchemeModel::query();
        !empty($where['schemeID'])
        && $query->where('schemeID', '=', $where['schemeID']);
        !empty($where['is_enable'])
        && $query->where('is_enable', '=', $where['is_enable']);
        $data = $query->paginate($perPage, $field);
        return ['code' => ErrorCode::SUCCESS, 'data' => $data];
    }

    /**
     * 根据龙收银价格方案同步龙收银价格
     * @param $schemeID
     * @return array
     */
    public function getCrmSchemeGoodsPriceBySchemeId($schemeID)
    {
        $resMsg = '根据方案ID获取商品详情执行完成-';
        $beginTime = time();
        $CrmGoodsData = [];
        $menuInfoArr =$this->lsyMainGoodsService->singlePullShopInfoMenu($schemeID);
        foreach ($menuInfoArr ['thirdPriLocalItemListVo']['itemList'] as $value) {
            $CrmGoodsData [] = [
                'schemeID' => $menuInfoArr['priLocal']['id'],
                'crm_goods_id' => $value['id'],
                'name' => $value['name'],
                'stdPrice' => $value['stdPrice'],
                'price' => $value['price'],
                'create_date' => date('Y-m-d',time()),
            ];
        }
        ShopSchemeGoodsPriceModel::query()->where('schemeID',$schemeID)->delete();
        ShopSchemeGoodsPriceModel::query()->insert($CrmGoodsData);
        $resMsg .='-消耗时间'.(time()-$beginTime).'s';
        // 同步后更新商品缓存
        $this->container->get(BuildGoodsService::class)->buildAllShopTimelyGoodsListToRedis(null);
        return ['code'=>ErrorCode::SUCCESS,'data'=>$resMsg];
    }

    /**
     * 用户全量获取余量接口（1.0 老库存）
     * @return array
     */
    public function getCompletePullArchInfoStock()
    {
        $resMsg = '用户全量获取余量接口';
        $beginTime = time();
        $LsyGoodsData =$this->lsyMainGoodsService->completePullArchInfoStock(1, 20000);
        $chunk_result = array_chunk($LsyGoodsData['itemList'], 1000);
        ShopLsyGoodsStockModel::query()->truncate();
        foreach ($chunk_result as $new_list) {
            $goodsData=[];
            foreach ($new_list as $k=>$value){
                $goodsData []= [
                    'itemId' => $value['itemId'],
                    'itemName' => $value['itemName'],
                    'itemType' => $value['itemType'],
                    'unitName' => $value['unitName'],
                    'classId' => $value['classId'],
                    'className' => $value['className'],
                    'isAutoRestore' => $value['isAutoRestore'],
                    'isGuQing' => $value['isGuQing'],
                    'surplusQuantity' => $value['surplusQuantity'],
                    'salesQuantity' => $value['salesQuantity'],
                    'limitQuantity' => $value['limitQuantity'],
                    'createShopId' => $value['createShopId'],
                    'create_date' => date('Y-m-d',time()),
                ];
            }
            ShopLsyGoodsStockModel::query()->insert($goodsData);
        }
        $resMsg .='-消耗时间'.(time()-$beginTime).'s';
        return ['code'=>ErrorCode::SUCCESS,'data'=>$resMsg];
    }

    /**
     * 手动全量拉取龙收银商品信息
     * @return array
     */
    public function getCrmLsyGoodsInfo()
    {
        $resMsg = '全量拉取龙收银商品信息-';
        $beginTime = time();
        $goodsData = [];
        $LsyGoodsData =$this->lsyMainGoodsService->CompletePullArchInfo(1);
        foreach ($LsyGoodsData['itemList'] as $value) {
            $goodsData [] = [
                'id' => $value['id'],
                'code' => $value['code'],
                'name' => $value['name'],
                'stdPrice' => $value['stdPrice'],
                'costPrice' => $value['costPrice'],
                'unitId' => $value['unitId'],
                'unitName' => $value['unitName'],
                'itemClassName' => $value['itemClassName'],
                'isEnable' => $value['isEnable'],
                'itemType' => $value['itemType'],
                'isBox' => $value['isBox'],
                'itemCode' => $value['itemCode'],
                'sdpCode' => $value['itemCode']-2000,
                'isMostUnit' => $value['isMostUnit'],
                'spicy' => $value['spicy']??'',
                'pinyin' => $value['pinyin'],
                'isSpicy' => $value['isSpicy']??'',
                'itemClassId' => $value['itemClassId'],
                'isPackage' => $value['isPackage'],
                'create_date' => date('Y-m-d',time()),
            ];
        }
        ShopLsyGoodsInfoModel::query()->truncate();
        ShopLsyGoodsInfoModel::query()->insert($goodsData);
        $resMsg .='-消耗时间'.(time()-$beginTime).'s';
        return ['code'=>ErrorCode::SUCCESS,'data'=>$resMsg];
    }
    /**
     * @param string $start_time
     * @param string $end_time
     * @param array $shop_code
     * @return array
     */
    public function getShopOrderInfoToLsy(string $start_time, string $end_time, array $shop_code){
        $shopIds = ShopModel::query()
            ->whereIn('lsy_shop_no', $shop_code)
            ->pluck('lsy_shop_no','shop_id');
        if (!$shopIds){
            return ['code' => 0, 'errorCode' => ErrorCode::NOT_EXIST, 'msg' => '店铺不存在'];
        }
        $shopIds = $shopIds->toArray();
        $diff = array_fill_keys(array_keys($shopIds), '0');
        $res = OrderModel::query()
            ->selectRaw('COUNT(order_no) as order_count,SUM(total_price) as total,shop_id')
            ->whereIn('shop_id', array_keys($shopIds))
            ->where('is_pay', Stakeholder::ORDER_PAID)
            ->whereBetween('pay_at', [$start_time, $end_time])
            ->groupBy(['shop_id'])
            ->get()
            ->toArray();
        $kz = KzRefundLogModel::query()
            ->selectRaw('SUM(refund_balance_money) as refund_amt,shop_id')
            ->whereIn('shop_id', array_keys($shopIds))
            ->whereBetween('create_time', [$start_time, $end_time])
            ->groupBy(['shop_id'])
            ->get()
            ->toArray();
        $wx = WxRefundLogModel::query()
            ->selectRaw('SUM(refund_wx_money) as refund_amt,shop_id')
            ->whereIn('shop_id', array_keys($shopIds))
            ->whereBetween('create_time', [$start_time, $end_time])
            ->groupBy(['shop_id'])
            ->get()
            ->toArray();
        $kz = array_column($kz, 'refund_amt', 'shop_id') + $diff;
        $wx = array_column($wx, 'refund_amt', 'shop_id') + $diff;
        foreach ($res as $k => $v){
            $res[$k]['shop_no'] = $shopIds[$v['shop_id']];
            $res[$k]['actual_amt'] = bcsub((string)$v['total'], bcadd((string)$kz[$v['shop_id']], (string)$wx[$v['shop_id']], 2), 2);
            unset($res[$k]['total'],$res[$k]['shop_id']);
        }
        return ['code' => 1, 'data' => $res, 'msg' => '获取数据成功'];
    }

    /**
     * @param array $where
     * @param int $perPage
     * @param array|string[] $field
     * @return array
     */
    public function goodsStockInfo(array $where, int $perPage = 30, array $field = ['*'])
    {
        $query = ShopLsyGoodsStockModel::query();
        !empty($where['itemId']) && $query->whereRaw('INSTR(itemId, ?) > 0', [trim($where['itemId'])]);
        if(!empty($where['shopGroup']) && $where['shopGroup'] != ''){
            $lsyShopNos = ShopModel::query() -> where('shop_group_id', trim($where['shopGroup'])) -> pluck('lsy_shop_no') -> toArray();
            $query->whereIn('createShopId', $lsyShopNos);
        }
        if(!empty($where['itemName']) && $where['itemName'] != ''){
            $goodsCrmCode = GoodsModel::query() -> whereRaw('INSTR(title, ?) > 0', [trim($where['itemName'])]) -> pluck('goods_crm_code')->toArray();
            $query->whereIn('itemId', array_unique($goodsCrmCode));
        }
        if(!empty($where['shopName']) && $where['shopName'] != ''){
            $lsyShopNo = ShopModel::query() -> where('shop_name', trim($where['shopName'])) -> value('lsy_shop_no');
            $query->where('createShopId', $lsyShopNo);
        }
        $res = $query -> Paginate($perPage, $field);

        return ['code' => ErrorCode::SUCCESS, 'data' => $res];
    }

    /**
     * @author ran
     * @date 2021-03-22 10:31
     * mailbox 466180170@qq.com
     */
    public function manualPushTakeOutChargeBack(int $id):array
    {
          $wxDedoLogArr =WxDedoLogModel::query()->where('id',$id)->first()->toArray();
          $order = $this->container->get(OrderService::class);
          $orderInfo = $order->findFirst(['order_no' => $wxDedoLogArr['order_no']])->toArray();
          if(empty($orderInfo['deNo']) || empty($orderInfo['deId'])) return $this->error(ErrorCode::SERVER_ERROR,'请优先处理异常外卖下单');
          $wxDeliverCommonInfo = $this->container->get(WxDeliverService::class)->common($orderInfo);
          $wxDedoLogArrInfo=json_decode($wxDedoLogArr['params_detail'],true);
          $wxDedoLogGoodsList =$wxDedoLogArrInfo['deItemList'];
          $shopArr = $wxDeliverCommonInfo['shopArr'];
          $orderGoodsArr = $wxDeliverCommonInfo['orderGoodsArr'];
          $orderGoodsListByGoodsId = collect($orderGoodsArr)->keyBy('itemCode')->toArray();
          $goodsListByGoodsId = $wxDeliverCommonInfo['goodsListByGoodsId'];
          foreach ($wxDedoLogGoodsList as $key=>$value) {
              $wxDedoLogGoodsList[$key]['id']=$orderGoodsListByGoodsId[$value['itemCode']]['goods_id'];
          }
          foreach($wxDedoLogGoodsList as $value){
              $itemCode=$goodsListByGoodsId[$value['id']]['wx_crm_code'];
              $deliverRefundGoodsArr[] = [
                  "itemCode" => $itemCode,
                  "itemName" => $value['itemName'],
                  "smItemFlg" => $value['smItemFlg'],
                  'qty' =>$value['qty'],
                  'pr' => $value['pr'],
                  'refundItemPrice' => $value['refundItemPrice']
              ];
          }
          $temp_data = [
            'mcID' => $shopArr['crm_mcid'],
            'deID' => $orderInfo['deId'],
            'deNo' => $orderInfo['deNo'],
            'deFrom' => $wxDedoLogArrInfo['deFrom'],
            'partRefundFlg' =>$wxDedoLogArrInfo['partRefundFlg'],
            'refundMoney' => $wxDedoLogArrInfo['refundMoney'],
            'reason' => $wxDedoLogArrInfo['reason'],
            'refundType' => $wxDedoLogArrInfo['refundType'],
            'businessNo' => $wxDedoLogArrInfo['businessNo'],
            'deItemList' =>$deliverRefundGoodsArr,
            'payInfo' =>$wxDedoLogArrInfo['payInfo']
          ];
          $res = $this->container->get(WxMainDeliverService::class)->refundDeliveryOfflineMapping($orderInfo, $temp_data);
          try {
                WxDedoLogModel::query()->where('id',$id)->update(['is_deleted'=>1]);
          }catch (Exception $e){
                return $this->error(ErrorCode::SERVER_ERROR,$e->getMessage());
          }
          if ($res['code'] == 1){
            if($res['data']['returnCode'] == 1 && $res['data']['errorText'] == '成功'){
                return $this->success();
            }
         }
         return $this->error(ErrorCode::SERVER_ERROR,$res['data']['errorText']);
    }

}
